import {
  type LoadHook,
  type RegisterHooksOptions,
  type ResolveHook,
} from "node:module";
import stripJsonComments from "strip-json-comments";

interface RegisterAsyncHooksOptions {
  /**
   * See [load hook](https://nodejs.org/docs/latest-v24.x/api/module.html#loadurl-context-nextload).
   * @default undefined
   */
  load?: LoadHook | undefined;
  /**
   * See [resolve hook](https://nodejs.org/docs/latest-v24.x/api/module.html#resolvespecifier-context-nextresolve).
   * @default undefined
   */
  resolve?: ResolveHook | undefined;
}

const mod: RegisterAsyncHooksOptions = {
  load: async (url, context, nextLoad) => {
    const nextResult = await nextLoad(url, context);
    // positive - from "*.json" with {type: "jsonc"}
    if (context.importAttributes.type === "jsonc") {
      return {
        ...context,
        format: "json",
        // todo - strip jsonc comments
        source: nextResult.source,
      };
    } else if (
      // objective - from '*.jsonc'
      url.endsWith(".jsonc") ||
      context.importAttributes.type === "json"
    ) {
      const nextResult = await nextLoad(url, context);
      return {
        ...context,
        format: "json",
        // todo - strip jsonc comments
        source: stripJsonComments(nextResult.source as string),
      };
    }
    // else if (context.conditions.includes("jsonc")) {
    //   return nextLoad(url, context);
    // }

    return nextResult;
  },
  resolve: async (specifier, context, nextResolve) => {
    const nextResult = await nextResolve(specifier);
    // positive - assert jsonc
    if (context.importAttributes.type === "jsonc") {
      return {
        ...context,
        format: "json",
        url: nextResult.url,
      };
    } else if (
      // objective - jsonc file
      specifier.endsWith(".jsonc") ||
      context.importAttributes.type === "json"
    ) {
      return {
        ...context,
        format: "json",
        url: nextResult.url,
      };
    }
    // else if (context.conditions.includes("jsonc")) {
    //   return nextResolve(specifier, context);
    // }

    return nextResult;
  },
};

export default mod;
